package com.atguigu.exam.service.impl;

import com.atguigu.exam.entity.AnswerRecord;
import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.AnswerRecordMapper;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.service.AIService;
import com.atguigu.exam.service.AnswerRecordService;
import com.atguigu.exam.service.ExamRecordService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.vo.ExamRankingVO;
import com.atguigu.exam.vo.GradingResult;
import com.atguigu.exam.vo.StartExamVo;
import com.atguigu.exam.vo.SubmitAnswerVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 考试记录Service实现类
 * 实现考试记录相关的业务逻辑
 */
@Service
public class ExamRecordServiceImpl extends ServiceImpl<ExamRecordMapper, ExamRecord> implements ExamRecordService {
    @Autowired
    private PaperService paperService;
    @Autowired
    private AnswerRecordService answerRecordService;
    @Autowired
    private AIService aiService;
    @Autowired
    private AnswerRecordMapper answerRecordMapper;

    @Override
    public ExamRecord startExam(StartExamVo startExamVo) {
        ExamRecord examRecord = baseMapper.selectOne(new LambdaQueryWrapper<ExamRecord>()
                .eq(ExamRecord::getStudentName, startExamVo.getStudentName())
                .eq(ExamRecord::getExamId, startExamVo.getPaperId())
                .eq(ExamRecord::getStatus, "进行中"));
        if (examRecord == null) {
            examRecord = new ExamRecord();
            examRecord.setStudentName(startExamVo.getStudentName());
            examRecord.setExamId(startExamVo.getPaperId());
            examRecord.setStartTime(LocalDateTime.now());
            examRecord.setStatus("进行中");
            baseMapper.insert(examRecord);
        }
        return examRecord;
    }

    @Override
    public ExamRecord getExamRecordDetilsById(Long id) {
        ExamRecord examRecord = baseMapper.selectById(id);
        Paper paper = paperService.getPaperById(examRecord.getExamId());
        List<Question> questions = paper.getQuestions();
        questions.sort(Comparator.comparing(Question::getType));
        paper.setQuestions(questions);
        examRecord.setPaper(paper);
        List<AnswerRecord> answerRecords = answerRecordService.list(new LambdaQueryWrapper<AnswerRecord>().eq(AnswerRecord::getExamRecordId, id));
        examRecord.setAnswerRecords(answerRecords);
        return examRecord;
    }

    @Override
    public void submitAnswers(Long examRecordId, List<SubmitAnswerVo> answers) {
        ExamRecord examRecord = baseMapper.selectById(examRecordId);
        examRecord.setEndTime(LocalDateTime.now());
        examRecord.setStatus("已完成");
        baseMapper.updateById(examRecord);
        List<AnswerRecord> answerRecords = answers.stream().map(answer -> new AnswerRecord(examRecordId, answer.getQuestionId(), answer.getUserAnswer())).collect(Collectors.toList());
        answerRecordService.saveBatch(answerRecords);
        gradePaper(examRecordId);
    }

    @Override
    public void deleteExamRecord(Integer id) {
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getId, id).eq(ExamRecord::getStatus, "进行中"));
        if (exists) {
            throw new ExamException(250, "该考试正在进行，无法删除");
        }
        answerRecordMapper.delete(new LambdaQueryWrapper<AnswerRecord>().eq(AnswerRecord::getExamRecordId, id));
        baseMapper.deleteById(id);
        }

    @Override
    public List<ExamRankingVO> getExamRanking(Integer paperId, Integer limit) {
        List<ExamRankingVO> list = baseMapper.getExamRanking(paperId, limit);
        return list;
    }


    public void gradePaper(Long examRecordId) {
        ExamRecord examRecord = getExamRecordDetilsById(examRecordId);
        List<Question> questions = examRecord.getPaper().getQuestions();
        Map<Long, Question> questionMap = questions.stream().collect(Collectors.toMap(Question::getId, question -> question));
        List<AnswerRecord> answerRecords = examRecord.getAnswerRecords();
        AtomicInteger correctCount = new AtomicInteger();
        answerRecords.forEach(answerRecord -> {
            Question question = questionMap.get(answerRecord.getQuestionId());
            String userAnswer = answerRecord.getUserAnswer();
            if (!"TEXT".equals(question.getType())) {
                if ("JUDGE".equals(question.getType())) {
                    userAnswer = userAnswer.equals("T") ? "TRUE" : "FALSE";
                }
                if (userAnswer.equals(question.getAnswer().getAnswer())) {
                    answerRecord.setScore(question.getPaperScore().intValue());
                    answerRecord.setIsCorrect(1);
                    correctCount.set(correctCount.get() + 1);
                } else {
                    answerRecord.setScore(0);
                    answerRecord.setIsCorrect(0);
                }
            } else {
                GradingResult gradingResult = aiService.gradeTextQuestions(question, userAnswer);
                Integer score = gradingResult.getScore();
                answerRecord.setScore(score);
                if (score.equals(0)) {
                    answerRecord.setIsCorrect(0);
                } else if (score.equals(question.getPaperScore().intValue())) {
                    answerRecord.setIsCorrect(1);
                    correctCount.set(correctCount.get() + 1);
                } else {
                    answerRecord.setIsCorrect(2);
                    answerRecord.setAiCorrection(gradingResult.getReason());
                    correctCount.set(correctCount.get() + 1);
                }
            }
            answerRecordMapper.updateById(answerRecord);
        });
        int totalPaperScore = questions.stream().mapToInt(q -> q.getPaperScore().intValue()).sum();
        int totalScore = answerRecords.stream().filter(ar -> ar.getIsCorrect() != 0).mapToInt(AnswerRecord::getScore).sum();
        examRecord.setScore(totalScore);
        examRecord.setStatus("已批阅");
        String answer = aiService.getExamAnswer(totalScore, totalPaperScore, questions.size(), correctCount);
        examRecord.setAnswers(answer);
        baseMapper.updateById(examRecord);
    }

}